<!DOCTYPE html>
<html lang="zh-CN">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>PlatService 测试页面</title>
    <style>
        :root {
            --primary-color: #4361ee;
            --success-color: #4caf50;
            --danger-color: #f44336;
            --warning-color: #ff9800;
            --info-color: #2196f3;
            --dark-color: #333;
            --light-color: #f8f9fa;
            --border-color: #dee2e6;
            --shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
            --transition: all 0.3s ease;
        }

        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font-family: 'Segoe UI', Tahoma, Geneva, Verdana, sans-serif;
            background: linear-gradient(135deg, #667eea 0%, #764ba2 100%);
            min-height: 100vh;
            padding: 20px;
        }

        .container {
            max-width: 1200px;
            margin: 0 auto;
            background: white;
            border-radius: 15px;
            box-shadow: 0 10px 30px rgba(0,0,0,0.2);
            overflow: hidden;
        }

        .header {
            background: linear-gradient(135deg, #2c3e50, #4a6491);
            color: white;
            padding: 25px;
            text-align: center;
            position: relative;
        }

        .header h1 {
            margin: 0;
            font-size: 28px;
            font-weight: 600;
        }

        .header p {
            margin-top: 8px;
            opacity: 0.9;
        }

        .quick-test {
            background: linear-gradient(135deg, var(--success-color), #8bc34a);
            color: white;
            padding: 15px 25px;
            border-radius: 50px;
            font-weight: 600;
            cursor: pointer;
            border: none;
            box-shadow: var(--shadow);
            transition: var(--transition);
            position: absolute;
            right: 25px;
            top: 50%;
            transform: translateY(-50%);
            display: flex;
            align-items: center;
            gap: 8px;
        }

        .quick-test:hover {
            transform: translateY(-50%) scale(1.05);
            box-shadow: 0 6px 12px rgba(0,0,0,0.2);
        }

        .quick-test:active {
            transform: translateY(-50%) scale(0.98);
        }

        .tabs {
            display: flex;
            background: #34495e;
            border-bottom: 1px solid #ddd;
            flex-wrap: wrap;
        }

        .tab {
            padding: 16px 24px;
            cursor: pointer;
            color: #ecf0f1;
            font-weight: 500;
            transition: var(--transition);
            border-bottom: 3px solid transparent;
        }

        .tab:hover {
            background: #3d566e;
        }

        .tab.active {
            background: #3498db;
            border-bottom: 3px solid #fff;
        }

        .tab-content {
            display: none;
            padding: 30px;
        }

        .tab-content.active {
            display: block;
            animation: fadeIn 0.3s ease;
        }

        @keyframes fadeIn {
            from { opacity: 0; transform: translateY(10px); }
            to { opacity: 1; transform: translateY(0); }
        }

        .form-group {
            margin-bottom: 20px;
        }

        label {
            display: block;
            margin-bottom: 8px;
            font-weight: 600;
            color: #2c3e50;
        }

        input, select {
            width: 100%;
            padding: 12px 15px;
            border: 1px solid #bdc3c7;
            border-radius: 6px;
            box-sizing: border-box;
            font-size: 15px;
            transition: var(--transition);
        }

        input:focus, select:focus {
            outline: none;
            border-color: var(--primary-color);
            box-shadow: 0 0 0 3px rgba(67, 97, 238, 0.2);
        }

        .btn {
            background: linear-gradient(135deg, var(--primary-color), #3a56d4);
            color: white;
            padding: 14px 20px;
            border: none;
            border-radius: 6px;
            cursor: pointer;
            font-size: 16px;
            font-weight: 600;
            transition: var(--transition);
            width: 100%;
            margin-top: 10px;
            box-shadow: var(--shadow);
        }

        .btn:hover {
            transform: translateY(-2px);
            box-shadow: 0 6px 12px rgba(0,0,0,0.2);
        }

        .btn:active {
            transform: translateY(0);
        }

        .btn-success {
            background: linear-gradient(135deg, var(--success-color), #3d8b40);
        }

        .btn-warning {
            background: linear-gradient(135deg, var(--warning-color), #e68a00);
        }

        .result {
            margin-top: 25px;
            padding: 20px;
            border-radius: 8px;
            white-space: pre-wrap;
            word-wrap: break-word;
            max-height: 400px;
            overflow-y: auto;
            display: none;
            box-shadow: var(--shadow);
            position: relative;
        }

        .result-header {
            display: flex;
            justify-content: space-between;
            align-items: center;
            margin-bottom: 15px;
            padding-bottom: 10px;
            border-bottom: 1px solid var(--border-color);
        }

        .result-title {
            font-weight: 600;
            font-size: 18px;
        }

        .close-result {
            background: none;
            border: none;
            font-size: 20px;
            cursor: pointer;
            color: #999;
        }

        .success {
            background-color: #e8f5e9;
            color: #2e7d32;
            border: 1px solid #c8e6c9;
        }

        .error {
            background-color: #ffebee;
            color: #c62828;
            border: 1px solid #ffcdd2;
        }

        .info-panel {
            background: #f8f9fa;
            border: 1px solid #e9ecef;
            border-radius: 8px;
            padding: 20px;
            margin-bottom: 25px;
            box-shadow: var(--shadow);
        }

        .info-panel h3 {
            margin-top: 0;
            color: #2c3e50;
            border-bottom: 1px solid var(--border-color);
            padding-bottom: 10px;
        }

        .info-item {
            margin-bottom: 12px;
            display: flex;
        }

        .info-label {
            font-weight: 600;
            display: inline-block;
            width: 120px;
            color: #495057;
        }

        .info-value {
            flex: 1;
            color: #212529;
        }

        .timestamp-controls {
            display: flex;
            gap: 10px;
            margin-bottom: 15px;
        }

        .timestamp-controls button {
            flex: 1;
            width: auto;
            padding: 10px;
            font-size: 14px;
        }

        .url-result {
            background: #e3f2fd;
            border: 1px solid #bbdefb;
            border-radius: 6px;
            padding: 15px;
            margin-top: 15px;
            display: none;
        }

        .url-result a {
            color: var(--primary-color);
            font-weight: 600;
            text-decoration: none;
            display: inline-block;
            padding: 10px 15px;
            background: white;
            border-radius: 4px;
            border: 1px solid var(--border-color);
            transition: var(--transition);
        }

        .url-result a:hover {
            background: #f1f8ff;
            transform: translateY(-2px);
        }

        .loader {
            display: none;
            text-align: center;
            padding: 20px;
        }

        .loader-spinner {
            border: 4px solid rgba(0, 0, 0, 0.1);
            border-left-color: var(--primary-color);
            border-radius: 50%;
            width: 30px;
            height: 30px;
            animation: spin 1s linear infinite;
            margin: 0 auto;
        }

        @keyframes spin {
            to { transform: rotate(360deg); }
        }

        .status-indicator {
            display: inline-block;
            width: 12px;
            height: 12px;
            border-radius: 50%;
            margin-right: 8px;
        }

        .status-success {
            background-color: var(--success-color);
        }

        .status-error {
            background-color: var(--danger-color);
        }

        @media (max-width: 768px) {
            body {
                padding: 10px;
            }

            .container {
                border-radius: 10px;
            }

            .header {
                padding: 20px 15px;
            }

            .header h1 {
                font-size: 22px;
            }

            .quick-test {
                position: static;
                transform: none;
                margin: 15px auto 0;
                width: calc(100% - 30px);
            }

            .tabs {
                flex-direction: column;
            }

            .tab-content {
                padding: 20px 15px;
            }

            .timestamp-controls {
                flex-direction: column;
            }
        }
    </style>
</head>
<body>
<div class="container">
    <div class="header">
        <h1>PlatService 测试页面</h1>
        <p>平台服务接口测试工具</p>
        <button class="quick-test" onclick="quickTest()">
            <span>⚡</span> 一键测试
        </button>
    </div>

    <div class="tabs">
        <div class="tab active" onclick="switchTab('launch')">获取游戏地址</div>
        <div class="tab" onclick="switchTab('transferIn')">商户上分</div>
        <div class="tab" onclick="switchTab('transferOut')">商户下分</div>
        <div class="tab" onclick="switchTab('balance')">查询余额</div>
        <div class="tab" onclick="switchTab('log')">转账日志</div>
        <div class="tab" onclick="switchTab('config')">游戏配置</div>
    </div>

    <div class="info-panel">
        <h3>测试代理信息</h3>
        <div class="info-item">
            <span class="info-label">代理编码:</span>
            <span class="info-value">test_agent</span>
        </div>
        <div class="info-item">
            <span class="info-label">MD5密钥:</span>
            <span class="info-value">test_md5_key@</span>
        </div>
        <div class="info-item">
            <span class="info-label">AES密钥:</span>
            <span class="info-value">test_aes_key!</span>
        </div>
    </div>

    <!-- 获取游戏大厅地址 -->
    <div id="launch" class="tab-content active">
        <h2>获取游戏大厅地址 (launchGame)</h2>
        <div class="form-group">
            <label for="launch_account">用户账号:</label>
            <input type="text" id="launch_account" value="test_user_001">
        </div>
        <div class="form-group">
            <label for="launch_pwd">密码:</label>
            <input type="password" id="launch_pwd" value="123456">
        </div>
        <div class="form-group">
            <label for="launch_game">游戏 (格式: gameId_level):</label>
            <input type="text" id="launch_game" value="601_0" placeholder="例如: 1_2">
        </div>
        <div class="form-group">
            <label for="launch_ip">IP地址:</label>
            <input type="text" id="launch_ip" value="127.0.0.1">
        </div>
        <button class="btn" onclick="launchGame()">获取游戏地址</button>
        <div class="loader" id="launch_loader">
            <div class="loader-spinner"></div>
            <p>正在获取游戏地址...</p>
        </div>
        <div id="launch_result" class="result"></div>
        <div id="launch_url" class="url-result">
            <p>游戏地址获取成功：</p>
            <a href="#" target="_blank" id="game_url">点击进入游戏</a>
        </div>
    </div>

    <!-- 商户上分 -->
    <div id="transferIn" class="tab-content">
        <h2>商户上分 (transferMoneyIn)</h2>
        <div class="form-group">
            <label for="in_account">用户账号:</label>
            <input type="text" id="in_account" value="test_user_001">
        </div>
        <div class="form-group">
            <label for="in_pwd">密码:</label>
            <input type="password" id="in_pwd" value="123456">
        </div>
        <div class="form-group">
            <label for="in_orderId">订单号 (格式: account:timestamp):</label>
            <input type="text" id="in_orderId" value="">
        </div>
        <div class="form-group">
            <label for="in_money">上分金额:</label>
            <input type="number" id="in_money" value="10000" min="1">
        </div>
        <button class="btn btn-success" onclick="transferMoneyIn()">执行上分</button>
        <div class="loader" id="in_loader">
            <div class="loader-spinner"></div>
            <p>正在执行上分操作...</p>
        </div>
        <div id="in_result" class="result"></div>
    </div>

    <!-- 商户下分 -->
    <div id="transferOut" class="tab-content">
        <h2>商户下分 (transferMoneyOut)</h2>
        <div class="form-group">
            <label for="out_account">用户账号:</label>
            <input type="text" id="out_account" value="test_user_001">
        </div>
        <div class="form-group">
            <label for="out_pwd">密码:</label>
            <input type="password" id="out_pwd" value="123456">
        </div>
        <div class="form-group">
            <label for="out_orderId">订单号 (格式: account:timestamp):</label>
            <input type="text" id="out_orderId" value="">
        </div>
        <div class="form-group">
            <label for="out_money">下分金额:</label>
            <input type="number" id="out_money" value="5000" min="1">
        </div>
        <button class="btn btn-warning" onclick="transferMoneyOut()">执行下分</button>
        <div class="loader" id="out_loader">
            <div class="loader-spinner"></div>
            <p>正在执行下分操作...</p>
        </div>
        <div id="out_result" class="result"></div>
    </div>

    <!-- 查询余额 -->
    <div id="balance" class="tab-content">
        <h2>查询余额 (getRemain)</h2>
        <div class="form-group">
            <label for="remain_account">用户账号:</label>
            <input type="text" id="remain_account" value="test_user_001">
        </div>
        <div class="form-group">
            <label for="remain_pwd">密码:</label>
            <input type="password" id="remain_pwd" value="123456">
        </div>
        <button class="btn" onclick="getRemain()">查询余额</button>
        <div class="loader" id="remain_loader">
            <div class="loader-spinner"></div>
            <p>正在查询余额...</p>
        </div>
        <div id="remain_result" class="result"></div>
    </div>

    <!-- 转账日志 -->
    <div id="log" class="tab-content">
        <h2>转账日志 (transferLog)</h2>
        <div class="form-group">
            <label for="log_account">用户账号:</label>
            <input type="text" id="log_account" value="test_user_001">
        </div>
        <div class="form-group">
            <label for="log_pwd">密码:</label>
            <input type="password" id="log_pwd" value="123456">
        </div>
        <div class="form-group">
            <label for="log_orderId">订单号 (可选):</label>
            <input type="text" id="log_orderId" placeholder="留空查询所有">
        </div>
        <div class="form-group">
            <label for="log_pageSize">每页数量:</label>
            <input type="number" id="log_pageSize" value="10" min="1" max="100">
        </div>
        <div class="form-group">
            <label for="log_pageNum">页码:</label>
            <input type="number" id="log_pageNum" value="1" min="1">
        </div>
        <div class="form-group">
            <label>时间范围:</label>
            <div class="timestamp-controls">
                <button class="btn" onclick="setTimeRange('log_startTime', 'log_endTime', 'today')">今天</button>
                <button class="btn" onclick="setTimeRange('log_startTime', 'log_endTime', 'yesterday')">昨天</button>
                <button class="btn" onclick="setTimeRange('log_startTime', 'log_endTime', 'week')">本周</button>
            </div>
        </div>
        <div class="form-group">
            <label for="log_startTime">开始时间:</label>
            <input type="datetime-local" id="log_startTime">
        </div>
        <div class="form-group">
            <label for="log_endTime">结束时间:</label>
            <input type="datetime-local" id="log_endTime">
        </div>
        <button class="btn" onclick="transferLog()">查询日志</button>
        <div class="loader" id="log_loader">
            <div class="loader-spinner"></div>
            <p>正在查询转账日志...</p>
        </div>
        <div id="log_result" class="result"></div>
    </div>

    <!-- 游戏配置 -->
    <div id="config" class="tab-content">
        <h2>游戏配置 (getGameConfig)</h2>
        <p>获取所有可用游戏配置信息</p>
        <button class="btn" onclick="getGameConfig()">获取游戏配置</button>
        <div class="loader" id="config_loader">
            <div class="loader-spinner"></div>
            <p>正在获取游戏配置...</p>
        </div>
        <div id="config_result" class="result"></div>
    </div>
</div>

<script>
    const API_BASE = "http://localhost:9998";

    // 初始化订单号
    function initOrderIds() {
        const now = Date.now();
        document.getElementById('in_orderId').value = `test_user_001:${now}`;
        document.getElementById('out_orderId').value = `test_user_001:${now + 1}`;
    }

    // 设置时间范围
    function setTimeRange(startId, endId, range) {
        const now = new Date();
        let start, end = now;

        switch(range) {
            case 'today':
                start = new Date(now.getFullYear(), now.getMonth(), now.getDate());
                break;
            case 'yesterday':
                end = new Date(now.getFullYear(), now.getMonth(), now.getDate());
                start = new Date(end.getTime() - 24*60*60*1000);
                break;
            case 'week':
                const day = now.getDay();
                const diff = now.getDate() - day + (day == 0 ? -6:1);
                start = new Date(now.setDate(diff));
                start.setHours(0, 0, 0, 0);
                break;
        }

        document.getElementById(startId).value = formatDateTimeLocal(start);
        document.getElementById(endId).value = formatDateTimeLocal(end);
    }

    // 格式化日期时间用于datetime-local输入框
    function formatDateTimeLocal(date) {
        const year = date.getFullYear();
        const month = String(date.getMonth() + 1).padStart(2, '0');
        const day = String(date.getDate()).padStart(2, '0');
        const hours = String(date.getHours()).padStart(2, '0');
        const minutes = String(date.getMinutes()).padStart(2, '0');
        return `${year}-${month}-${day}T${hours}:${minutes}`;
    }

    // 页面加载时初始化
    window.onload = function() {
        initOrderIds();
        setTimeRange('log_startTime', 'log_endTime', 'today');
    };

    // 切换标签页
    function switchTab(tabName) {
        // 隐藏所有标签内容
        document.querySelectorAll('.tab-content').forEach(tab => {
            tab.classList.remove('active');
        });

        // 移除所有标签的活动状态
        document.querySelectorAll('.tab').forEach(tab => {
            tab.classList.remove('active');
        });

        // 显示选中的标签内容
        document.getElementById(tabName).classList.add('active');

        // 设置当前标签为活动状态
        event.target.classList.add('active');
    }

    // 生成签名
    function generateSign(agent, timeStamp, md5Key) {
        // 模拟MD5签名生成过程
        // 实际签名规则: 移除首尾各2位，第9和17位后各移除2位
        const rawSign = CryptoJS.MD5(agent + timeStamp + md5Key).toString();

        // 按照PlatRequestFilter中的规则处理签名
        let processedSign = "xx" + rawSign.substring(0, 9) + "xx" +
            rawSign.substring(9, 17) + "xx" +
            rawSign.substring(17) + "xx";
        return processedSign;
    }

    // 发送请求的通用方法
    async function sendRequest(path, method, data, loaderId) {
        if (loaderId) {
            document.getElementById(loaderId).style.display = 'block';
        }

        const agent = "test_agent";
        const timeStamp = Date.now();
        const randno = Math.floor(Math.random() * 1000000);
        const md5Key = "test_md5_key@";
        const sign = generateSign(agent, timeStamp, md5Key);

        const params = new URLSearchParams();
        params.append('agent', agent);
        params.append('timeStamp', timeStamp);
        params.append('randno', randno);
        params.append('sign', sign);

        let url = `${API_BASE}/plat${path}`;
        if (method === 'GET' && data) {
            Object.keys(data).forEach(key => {
                if (data[key] !== undefined && data[key] !== '') {
                    params.append(key, data[key]);
                }
            });
            url += '?' + params.toString();
        } else {
            url += '?' + params.toString();
        }

        const options = {
            method: method,
            headers: {
                'Content-Type': 'application/json'
            }
        };
        if (method === 'POST' && data) {
            options.body = JSON.stringify(data);
        }

        try {
            const response = await fetch(url, options);
            const result = await response.json();
            return {success: response.ok, status: response.status, data: result};
        } catch (error) {
            return {success: false, error: error.message};
        } finally {
            if (loaderId) {
                document.getElementById(loaderId).style.display = 'none';
            }
        }
    }

    // 显示结果
    function showResult(elementId, result, title = "响应结果") {
        const resultElement = document.getElementById(elementId);
        const resultHeader = document.createElement('div');
        resultHeader.className = 'result-header';

        const statusIndicator = document.createElement('div');
        statusIndicator.className = `status-indicator ${result.success ? 'status-success' : 'status-error'}`;

        const titleElement = document.createElement('div');
        titleElement.className = 'result-title';
        titleElement.textContent = title;

        const closeButton = document.createElement('button');
        closeButton.className = 'close-result';
        closeButton.innerHTML = '&times;';
        closeButton.onclick = () => {
            resultElement.style.display = 'none';
        };

        resultHeader.appendChild(statusIndicator);
        resultHeader.appendChild(titleElement);
        resultHeader.appendChild(closeButton);

        if (result.success) {
            resultElement.innerHTML = '';
            resultElement.appendChild(resultHeader);
            const content = document.createElement('div');
            content.textContent = JSON.stringify(result.data, null, 2);
            resultElement.appendChild(content);
            resultElement.className = "result success";
        } else {
            resultElement.innerHTML = '';
            resultElement.appendChild(resultHeader);
            const content = document.createElement('div');
            content.textContent = `错误 ${result.status || ''}: ${result.error || JSON.stringify(result.data)}`;
            resultElement.appendChild(content);
            resultElement.className = "result error";
        }
        resultElement.style.display = "block";

        // 滚动到结果区域
        resultElement.scrollIntoView({ behavior: 'smooth' });
    }

    // 获取游戏大厅地址
    async function launchGame() {
        const data = {
            account: document.getElementById('launch_account').value,
            pwd: document.getElementById('launch_pwd').value,
            game: document.getElementById('launch_game').value,
            memberIp: document.getElementById('launch_ip').value
        };

        const result = await sendRequest('/launchGame', 'POST', data, 'launch_loader');
        showResult('launch_result', result, "获取游戏地址结果");

        // 如果成功，显示可点击的URL
        const urlResult = document.getElementById('launch_url');
        const gameUrl = document.getElementById('game_url');
        if (result.success && result.data.url) {
            gameUrl.href = result.data.url;
            gameUrl.textContent = result.data.url;
            urlResult.style.display = 'block';
        } else {
            urlResult.style.display = 'none';
        }
    }

    // 商户上分
    async function transferMoneyIn() {
        const data = {
            account: document.getElementById('in_account').value,
            pwd: document.getElementById('in_pwd').value,
            orderId: document.getElementById('in_orderId').value,
            money: parseInt(document.getElementById('in_money').value)
        };

        const result = await sendRequest('/transferIn', 'POST', data, 'in_loader');
        showResult('in_result', result, "上分操作结果");
    }

    // 商户下分
    async function transferMoneyOut() {
        const data = {
            account: document.getElementById('out_account').value,
            pwd: document.getElementById('out_pwd').value,
            orderId: document.getElementById('out_orderId').value,
            money: parseInt(document.getElementById('out_money').value)
        };

        const result = await sendRequest('/transferOut', 'POST', data, 'out_loader');
        showResult('out_result', result, "下分操作结果");
    }

    // 查询余额
    async function getRemain() {
        const data = {
            account: document.getElementById('remain_account').value,
            pwd: document.getElementById('remain_pwd').value
        };

        const result = await sendRequest('/remain', 'POST', data, 'remain_loader');
        showResult('remain_result', result, "查询余额结果");
    }

    // 转账日志
    async function transferLog() {
        const startTime = new Date(document.getElementById('log_startTime').value).getTime() || 0;
        const endTime = new Date(document.getElementById('log_endTime').value).getTime() || Date.now();

        const data = {
            account: document.getElementById('log_account').value,
            pwd: document.getElementById('log_pwd').value,
            orderId: document.getElementById('log_orderId').value || undefined,
            pageSize: parseInt(document.getElementById('log_pageSize').value),
            pageNum: parseInt(document.getElementById('log_pageNum').value),
            startTime: startTime,
            endTime: endTime
        };

        const result = await sendRequest('/transferLog', 'POST', data, 'log_loader');
        showResult('log_result', result, "转账日志查询结果");
    }

    // 游戏配置
    async function getGameConfig() {
        const result = await sendRequest('/gameConfig', 'GET', null, 'config_loader');
        showResult('config_result', result, "游戏配置信息");
    }

    // 一键测试功能
    async function quickTest() {
        // 生成随机账户
        const randomAccount = `user_${Math.floor(Math.random() * 1000000)}`;
        const orderId = `${randomAccount}:${Date.now()}`;

        // 显示提示信息
        alert(`开始一键测试流程:\n1. 创建随机账户: ${randomAccount}\n2. 上分 1,000,000\n3. 获取游戏大厅地址`);

        // 上分 1,000,000
        const transferData = {
            account: randomAccount,
            pwd: "123456",
            orderId: orderId,
            money: 1000000
        };

        document.getElementById('in_loader').style.display = 'block';
        const transferResult = await sendRequest('/transferIn', 'POST', transferData, 'in_loader');

        if (!transferResult.success) {
            alert("上分失败，请检查服务状态");
            return;
        }

        // 获取游戏大厅地址
        const launchData = {
            account: randomAccount,
            pwd: "123456",
            game: "601_0",
            memberIp: "127.0.0.1"
        };

        document.getElementById('launch_loader').style.display = 'block';
        const launchResult = await sendRequest('/launchGame', 'POST', launchData, 'launch_loader');
        console.log(launchResult)
        if (launchResult.success) {
            // 跳转到游戏地址
            console.log(launchResult.data.data.url)
            window.open(launchResult.data.data.url, '_blank');
        } else {
            alert("获取游戏地址失败，请检查服务状态" + launchResult.data.url);
        }
    }
</script>

<!-- 引入 CryptoJS 用于 MD5 签名计算 -->
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/4.1.1/crypto-js.min.js"></script>
</body>
</html>
